using System;
using System.Collections.Generic;
using GGameFramework.Core.Pool;
using QFramework;
using UnityEngine;
using IPoolable = GGameFramework.Core.Pool.IPoolable;

namespace GGameFramework.Runtime
{
    public class PoolComponent : FrameworkComponent
    {
        public override FrameworkComponentPriority Priority => FrameworkComponentPriority.Core;

        PoolManager _poolManager;

        protected override void Awake()
        {
            base.Awake();
            
            _poolManager = FrameworkEntry.GetModule<PoolManager>();
        }

        #region 引用类型对象池操作

        /// <summary>
        /// 创建引用类型对象池
        /// </summary>
        public IReferencePool<T> CreateReferencePool<T>(
            Func<T> createFunc,
            Action<T> onSpawn = null,
            Action<T> onRecycle = null,
            Action<T> onDestroy = null,
            int initialCapacity = 5,
            int maxSize = 100,
            bool isDynamic = true) where T : ReferencePoolable
        {
            return _poolManager.CreateReferencePool(createFunc, onSpawn, onRecycle, onDestroy, initialCapacity, maxSize, isDynamic);
        }
        
        /// <summary>
        /// 从引用类型对象池获取对象
        /// </summary>
        public T SpawnFromReferencePool<T>() where T : ReferencePoolable
        {
            return _poolManager.SpawnFromReferencePool<T>();
        }
        
        /// <summary>
        /// 回收对象到引用类型对象池
        /// </summary>
        public void RecycleToReferencePool<T>(T obj) where T : ReferencePoolable
        {
            _poolManager.RecycleToReferencePool(obj);
        }
        
        /// <summary>
        /// 销毁引用类型对象池
        /// </summary>
        public void DestroyReferencePool<T>() where T : class
        {
            _poolManager.DestroyReferencePool<T>();
        }
        
        /// <summary>
        /// 获取引用类型对象池的所有存储对象
        /// </summary>
        public List<T> GetAllReferencePoolObjects<T>() where T : ReferencePoolable
        {
            return _poolManager.GetAllReferencePoolObjects<T>();
        }
        
        /// <summary>
        /// 预热引用类型对象池
        /// </summary>
        public void PrewarmReferencePool<T>(int count) where T : ReferencePoolable
        {
            _poolManager.PrewarmReferencePool<T>(count);
        }
        
        /// <summary>
        /// 获取引用类型对象池统计信息
        /// </summary>
        public PoolStatistics GetReferencePoolStatistics<T>() where T : ReferencePoolable
        {
            return _poolManager.GetReferencePoolStatistics<T>();
        }
        
        /// <summary>
        /// 检查引用类型对象池是否存在
        /// </summary>
        public bool HasReferencePool<T>() where T : class
        {
            return _poolManager.HasReferencePool<T>();
        }

        #endregion

        #region GameObject对象池操作

        /// <summary>
        /// 创建GameObject对象池
        /// </summary>
        public IGameObjectPool<T> CreateGameObjectPool<T>(
            GameObjectPoolable prefab,
            Transform root = null,
            int initialCapacity = 10,
            int maxSize = 50,
            bool dynamic = false) where T : GameObjectPoolable
        {

            if(_poolManager.HasGameObjectPool<T>(prefab))
            {
                Debug.Log($"GameObjectPool already exists: {prefab.name}");
                return _poolManager.GetGameObjectPool<T>(prefab);
            }

            // 创建池根节点
            var poolRoot = new GameObject($"{prefab.name}_Pool");
            poolRoot.transform.SetParent(root ?? transform);
            
            Func<T> createFunc = () =>
            {
                var go = UnityEngine.Object.Instantiate(prefab, poolRoot.transform);
                go.name = prefab.name;
                return go as T;
            };

            Action<T> onSpawn = obj => 
            {
                // GameObjectPool会自动处理激活
            };
            Action<T> onRecycle = obj => 
            {
                // GameObjectPool会自动处理关闭
            };
            Action<T> onDestroy = obj => 
            {
                if (obj != null)
                    UnityEngine.Object.Destroy(obj.gameObject);
            };
            
            return _poolManager.CreateGameObjectPool(prefab, createFunc, onSpawn, onRecycle, onDestroy, initialCapacity, maxSize, dynamic, poolRoot.transform);
        }
        
        /// <summary>
        /// 从GameObject对象池获取对象
        /// </summary>
        public T SpawnFromGameObjectPool<T>(GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            var pool = _poolManager.GetGameObjectPool<T>(prefab);
            if (pool == null)
            {
                pool = CreateGameObjectPool<T>(prefab, transform);
            }
            return pool.Spawn();
        }
        
        /// <summary>
        /// 回收对象到GameObject对象池
        /// </summary>
        public void RecycleToGameObjectPool<T>(T obj, GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            if (obj == null || prefab == null) return;
        
            _poolManager.RecycleToGameObjectPool(obj, prefab);
        }
        
        /// <summary>
        /// 回收GameObject对象到对象池（非泛型版本，更灵活）
        /// </summary>
        public void RecycleToGameObjectPool(GameObjectPoolable obj, GameObjectPoolable prefab)
        {
            if (obj == null || prefab == null) return;
            
            // 直接使用PoolManager的通用回收方法，它会自动处理类型匹配
            _poolManager.Recycle(obj, prefab);
        }
        
        /// <summary>
        /// 销毁GameObject对象池
        /// </summary>
        public void DestroyGameObjectPool<T>(GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            _poolManager.DestroyGameObjectPool<T>(prefab);
        }
        
        /// <summary>
        /// 获取GameObject对象池的所有存储对象
        /// </summary>
        public List<T> GetAllGameObjectPoolObjects<T>(GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            return _poolManager.GetAllGameObjectPoolObjects<T>(prefab);
        }
        
        /// <summary>
        /// 预热GameObject对象池
        /// </summary>
        public void PrewarmGameObjectPool<T>(GameObjectPoolable prefab, int count) where T : GameObjectPoolable
        {
            _poolManager.PrewarmGameObjectPool<T>(prefab, count);
        }
        
        /// <summary>
        /// 获取GameObject对象池统计信息
        /// </summary>
        public PoolStatistics GetGameObjectPoolStatistics<T>(GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            return _poolManager.GetGameObjectPoolStatistics<T>(prefab);
        }
        
        /// <summary>
        /// 检查GameObject对象池是否存在
        /// </summary>
        public bool HasGameObjectPool<T>(GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            return _poolManager.HasGameObjectPool<T>(prefab);
        }
        
        /// <summary>
        /// 便捷方法：创建GameObject对象池并自动管理根节点
        /// </summary>
        public IGameObjectPool<T> CreateGameObjectPoolAuto<T>(T prefab, int initialCapacity = 10, int maxSize = 50, bool dynamic = false) where T : GameObjectPoolable
        {
            return CreateGameObjectPool<T>(prefab, transform, initialCapacity, maxSize, dynamic);
        }
        
        /// <summary>
        /// 便捷方法：从GameObject对象池获取对象（自动创建池）
        /// </summary>
        public T SpawnFromGameObjectPoolAuto<T>(T prefab) where T : GameObjectPoolable
        {
            return SpawnFromGameObjectPool<T>(prefab);
        }
        
        /// <summary>
        /// 获取GameObject对象池的根节点
        /// </summary>
        public Transform GetGameObjectPoolRoot<T>(T prefab) where T : GameObjectPoolable
        {
            var poolName = $"{prefab.name}_Pool";
            var root = transform.Find(poolName);
            if (root == null)
            {
                Debug.LogWarning($"未找到对象池根节点: {poolName}");
            }
            return root;
        }
        
        /// <summary>
        /// 隐藏GameObject对象池的所有对象
        /// </summary>
        public void HideGameObjectPool<T>(T prefab) where T : GameObjectPoolable
        {
            var root = GetGameObjectPoolRoot(prefab);
            if (root != null)
            {
                root.gameObject.SetActive(false);
            }
        }
        
        /// <summary>
        /// 显示GameObject对象池的所有对象
        /// </summary>
        public void ShowGameObjectPool<T>(T prefab) where T : GameObjectPoolable
        {
            var root = GetGameObjectPoolRoot(prefab);
            if (root != null)
            {
                root.gameObject.SetActive(true);
            }
        }

        #endregion

        #region 通用操作

        /// <summary>
        /// 智能回收：自动判断是引用类型对象池还是GameObject对象池
        /// </summary>
        public void Recycle<T>(T obj, GameObjectPoolable prefab = null) where T : IPoolable
        {
            _poolManager.Recycle(obj, prefab);
        }
        
        /// <summary>
        /// 通用回收方法，自动推断类型
        /// </summary>
        public void Recycle(GameObjectPoolable obj, GameObjectPoolable prefab = null)
        {
            _poolManager.Recycle(obj, prefab);
        }
        
        /// <summary>
        /// 获取所有引用类型对象池名称
        /// </summary>
        public List<string> GetAllReferencePoolNames()
        {
            return _poolManager.GetAllReferencePoolNames();
        }
        
        /// <summary>
        /// 获取所有GameObject对象池信息
        /// </summary>
        public Dictionary<string, int> GetAllGameObjectPoolInfo()
        {
            return _poolManager.GetAllGameObjectPoolInfo();
        }
        
        /// <summary>
        /// 清空所有对象池
        /// </summary>
        public void ClearAllPools()
        {
            _poolManager.ClearAllPools();
        }

        /// <summary>
        /// 获取所有对象池统计信息
        /// </summary>
        public Dictionary<string, PoolStatistics> GetAllPoolStatistics()
        {
            return _poolManager.GetAllPoolStatistics();
        }
        
        /// <summary>
        /// 调试：打印所有对象池信息
        /// </summary>
        public void DebugPrintAllPools()
        {
            _poolManager.DebugPrintAllPools();
        }
        
        /// <summary>
        /// 调试：检查对象池状态
        /// </summary>
        public void DebugCheckPoolStatus<T>(T obj, GameObjectPoolable prefab) where T : GameObjectPoolable
        {
            Debug.Log($"=== 对象池状态检查 ===");
            Debug.Log($"对象类型: {obj.GetType().Name}");
            Debug.Log($"目标泛型类型: {typeof(T).Name}");
            Debug.Log($"预制体名称: {prefab.name}");
            Debug.Log($"预制体ID: {prefab.GetInstanceID()}");
            Debug.Log($"GameObject对象池存在: {HasGameObjectPool<T>(prefab)}");
            // 获取池的详细信息
            var pool = _poolManager.GetGameObjectPool<T>(prefab);
            if (pool != null)
            {
                Debug.Log($"池类型: {pool.GetType().Name}");
                Debug.Log($"池中对象类型: {pool.PoolType.Name}");
                Debug.Log($"池大小: {pool.Count}");
            }
            
            Debug.Log($"=====================");
        }

        #endregion
    }
}